#include "SceneCoordSpaceInfo.h"


SceneCoordSpaceInfo::SceneCoordSpaceInfo (float width, float height)
{
  _width = width;
  _height = height;

  _scale = 2.0f / _width;
  _position[0] = -_width / 2.0f;
  _position[1] = -_height / 2.0f;
  _position[2] = -100.0f;
}

SceneCoordSpaceInfo::SceneCoordSpaceInfo (FileStreamIn& input)
{
  input >> (*this);
}
void SceneCoordSpaceInfo::adjust_pos (float dx, float dy, float dz)
{
  _position[0] += dx;
  _position[1] += dy;
  _position[2] += dz;
}

void SceneCoordSpaceInfo::adjust_angle (float dx, float dy, float dz)
{
  _rotation[0] += dx;
  _rotation[1] += dy;
  _rotation[2] += dz;
}

void SceneCoordSpaceInfo::transform ()
{
  glScalef (_scale, _scale, _scale);
  glTranslatef (_position[0], _position[1], _position[2]);
  glRotatef (_rotation[0], 1.0f, 0.0f, 0.0f);
  glRotatef (_rotation[1], 0.0f, 1.0f, 0.0f);
  glRotatef (_rotation[2], 0.0f, 0.0f, 1.0f);
}

void SceneCoordSpaceInfo::show_calibration_point (int pointIndex,
                                                  OUT Array< float >& pointStore)
{

  pointStore[0] = float (pointIndex % 3) * (_width / 2.0f);
  pointStore[1] = float (pointIndex / 3) * (_height / 2.0f);

  show_point (pointStore[0], pointStore[1]);

}


void SceneCoordSpaceInfo::show_calibration_process (int pointIndex, float percent)
{

  float x = float (pointIndex % 3) * (_width / 2.0f);
  float y = float (pointIndex / 3) * (_height / 2.0f);

  start_draw ();

  glColor3f (0.5f, 0.0f, 0.0f);
  draw_sector (x, y, 2.0f, percent * 360.0f, 0.0f);
  
  end_draw ();

}


void SceneCoordSpaceInfo::show_border ()
{

  start_draw ();

  glColor3f (0.4f, 0.5f, 0.4f);
  glBegin (GL_LINE_LOOP);
  glVertex3f (0.0f, 0.0f, 0.0f);
  glVertex3f (_width, 0.0f, 0.0f);
  glVertex3f (_width, _height, 0.0f);
  glVertex3f (0.0f, _height, 0.0f);
  glEnd ();

  end_draw ();

}


void SceneCoordSpaceInfo::show_point (float x, float y)
{

  start_draw ();

  draw_circle (x, y, 1.0f);
 
  end_draw ();

}



// ========================================================================
// Private functions
// ========================================================================


void SceneCoordSpaceInfo::start_draw ()
{

  glPushMatrix ();
  transform ();

  glPushAttrib (GL_CURRENT_BIT);
  glColor3f (0.5f, 0.5f, 0.5f);
  
  glPushAttrib (GL_ENABLE_BIT);
  glDisable (GL_LIGHTING);
  
}


void SceneCoordSpaceInfo::end_draw ()
{

  glPopAttrib ();
  glPopAttrib ();
  glPopMatrix ();

}

void SceneCoordSpaceInfo::draw_sector (float x, float y, float r,
                                       float endDegree /*= 360*/,
                                       float startDegree /*= 0*/)
{
  
  float dToR =  PI / 180.0f;
  float endRad = endDegree * dToR;
  float startRad = startDegree * dToR;
  float deltaRad = 10.0f * dToR;

  glTranslatef (x, y, 0.0f);

  glBegin (GL_TRIANGLE_FAN);

  glVertex3f (0.0f, 0.0f, 0.0f);

  for (float i = startRad; i < endRad; i += deltaRad)
    glVertex3f (r * cos (i), r * sin (i), 0.0f);

  glEnd ();

}

void SceneCoordSpaceInfo::draw_circle (float x, float y, float r)
{
  draw_sector (x, y, r);
}

FileStreamOut& operator<< (FileStreamOut& output, const SceneCoordSpaceInfo& data)
{
  output.bin_write<float> (data._position.data (), 3);
  output.bin_write<float> (data._rotation.data (), 3);
  output.bin_write<float> (&data._scale);
  output.bin_write<float> (&data._width);
  output.bin_write<float> (&data._height);
  return output;
}

FileStreamIn& operator>> (FileStreamIn& input, SceneCoordSpaceInfo& data)
{
  float pos[3];
  float rot[3];
  if (!input)
    return input;
  input.bin_read<float> (pos, 3);
  input.bin_read<float> (rot, 3);
  data._position = Position3f (pos);
  data._rotation = Rotation3f (rot);
  input.bin_read<float> (&data._scale);
  input.bin_read<float> (&data._width);
  input.bin_read<float> (&data._height);
  return input;
}
